package com.atguigu.juc;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * @Author: shenhao
 * @CreatTime: 2024/10/24 14:13
 * @Version: 1.0
 * 【强制】必须回收自定义的ThreadLocal变量，尤其在线程池场景下，线程经常会被复用，如果不清理
 *  * 自定义的ThreadLocal变量，可能会影响后续业务逻辑和造成内存泄露等问题。尽量在代理中使用
 *  * try-finally块进行回收。
 *  每次结束业务，需要清空数据结束上一个顾客的数据，不然复用到了前一个顾客的数据，不体面
 */
public class ThreadLocalDemoV2 {
    public static void main(String[] args) {
        MyData data = new MyData();
        ExecutorService fixedThreadPool = Executors.newFixedThreadPool(3);
        try{
            for (int i = 0; i < 10; i++) {
                int finalI = i;
                fixedThreadPool.submit(()->{
                    try{
                        Integer before = data.threadLocalField.get();
                        data.add();
                        Integer after = data.threadLocalField.get();
                        System.out.println(Thread.currentThread().getName() + "工作窗口受理第:"+ finalI+"个顾客 before: " + before + ",after: " + after);
                    } catch (Exception e){
                        e.printStackTrace();
                    } finally {
                        data.threadLocalField.remove();
                    }
                });
            }
        } catch (Exception e){
            e.printStackTrace();
        } finally {
            fixedThreadPool.shutdown();
        }

    }
}

class MyData{
    ThreadLocal<Integer> threadLocalField = ThreadLocal.withInitial(() -> 0);

    public void add(){
        threadLocalField.set(threadLocalField.get() + 1);
    }
}
